"""
学习分析系统 - 数据模型
"""
from django.db import models
from django.contrib.auth import get_user_model
from django.utils import timezone
from django.core.cache import cache
from django.db.models import Count, Avg, StdDev
from decimal import Decimal
import uuid

from apps.core.models import TimeStampedModel

User = get_user_model()


class LearningActivity(TimeStampedModel):
    """
    学习活动记录
    记录学生在平台上的所有学习行为
    """
    class ActivityType(models.TextChoices):
        LOGIN = 'login', '登录'
        LOGOUT = 'logout', '登出'
        VIEW_COURSE = 'view_course', '查看课程'
        START_EXAM = 'start_exam', '开始考试'
        SUBMIT_EXAM = 'submit_exam', '提交考试'
        VIEW_QUESTION = 'view_question', '查看题目'
        ANSWER_QUESTION = 'answer_question', '回答题目'
        WATCH_VIDEO = 'watch_video', '观看视频'
        DOWNLOAD_MATERIAL = 'download_material', '下载资料'
        FORUM_POST = 'forum_post', '发帖'
        FORUM_REPLY = 'forum_reply', '回复'

    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='learning_activities',
        verbose_name='用户'
    )

    # 活动信息
    activity_type = models.CharField('活动类型', max_length=50, choices=ActivityType.choices)
    activity_name = models.CharField('活动名称', max_length=200)
    description = models.TextField('活动描述', blank=True)

    # 活动对象
    content_type = models.ForeignKey(
        'contenttypes.ContentType',
        on_delete=models.CASCADE,
        null=True,
        blank=True
    )
    object_id = models.UUIDField(null=True, blank=True)
    related_object = models.GenericForeignKey('content_type', 'object_id')

    # 活动数据
    duration = models.IntegerField('持续时间(秒)', null=True, blank=True)
    score = models.DecimalField('得分', max_digits=6, decimal_places=2, null=True, blank=True)
    completion_rate = models.DecimalField('完成率', max_digits=5, decimal_places=2, null=True, blank=True)

    # 技术信息
    ip_address = models.GenericIPAddressField('IP地址', null=True, blank=True)
    user_agent = models.TextField('用户代理', blank=True)
    device_info = models.JSONField('设备信息', default=dict, blank=True)

    # 地理位置
    location = models.JSONField('地理位置', default=dict, blank=True)

    # 额外数据
    metadata = models.JSONField('元数据', default=dict, blank=True)

    class Meta:
        db_table = 'learning_activities'
        verbose_name = '学习活动'
        verbose_name_plural = '学习活动'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['user', 'activity_type']),
            models.Index(fields=['activity_type', 'created_at']),
            models.Index(fields=['created_at']),
            models.Index(fields=['content_type', 'object_id']),
        ]

    def __str__(self):
        return f"{self.user.real_name} - {self.get_activity_type_display()}"


class LearningSession(TimeStampedModel):
    """
    学习会话
    记录用户的一次完整学习过程
    """
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='learning_sessions',
        verbose_name='用户'
    )

    # 会话信息
    session_id = models.CharField('会话ID', max_length=100, unique=True)
    start_time = models.DateTimeField('开始时间', auto_now_add=True)
    end_time = models.DateTimeField('结束时间', null=True, blank=True)
    duration = models.IntegerField('持续时间(秒)', null=True, blank=True)

    # 学习内容
    courses_viewed = models.JSONField('查看的课程', default=list, blank=True)
    questions_answered = models.JSONField('回答的题目', default=list, blank=True)
    exams_taken = models.JSONField('参加的考试', default=list, blank=True)
    materials_downloaded = models.JSONField('下载的资料', default=list, blank=True)

    # 会话统计
    total_activities = models.IntegerField('总活动数', default=0)
    productive_time = models.IntegerField('有效学习时间(秒)', default=0)
    idle_time = models.IntegerField('空闲时间(秒)', default=0)

    # 技术信息
    ip_address = models.GenericIPAddressField('IP地址')
    user_agent = models.TextField('用户代理', blank=True)
    device_type = models.CharField('设备类型', max_length=50, blank=True)

    # 会话质量
    engagement_score = models.DecimalField('参与度评分', max_digits=3, decimal_places=2, null=True, blank=True)
    effectiveness_score = models.DecimalField('效果评分', max_digits=3, decimal_places=2, null=True, blank=True)

    class Meta:
        db_table = 'learning_sessions'
        verbose_name = '学习会话'
        verbose_name_plural = '学习会话'
        ordering = ['-start_time']
        indexes = [
            models.Index(fields=['user', 'start_time']),
            models.Index(fields=['session_id']),
            models.Index(fields=['start_time']),
            models.Index(fields=['device_type']),
        ]

    def __str__(self):
        return f"{self.user.real_name} - {self.session_id}"

    def calculate_duration(self):
        """计算会话持续时间"""
        if self.end_time and self.start_time:
            self.duration = (self.end_time - self.start_time).total_seconds()
            self.save(update_fields=['duration'])

    def calculate_engagement(self):
        """计算参与度评分"""
        if self.duration and self.duration > 0:
            # 基于活动密度和有效学习时间计算
            activity_density = self.total_activities / (self.duration / 60)  # 每分钟活动数
            productive_ratio = self.productive_time / self.duration if self.duration > 0 else 0

            # 综合评分 (0-100)
            self.engagement_score = min(100, (activity_density * 10 + productive_ratio * 80))
            self.save(update_fields=['engagement_score'])


class LearningPath(TimeStampedModel):
    """
    学习路径
    为学生推荐的学习计划
    """
    class Status(models.TextChoices):
        ACTIVE = 'active', '进行中'
        COMPLETED = 'completed', '已完成'
        PAUSED = 'paused', '暂停'
        CANCELLED = 'cancelled', '取消'

    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='learning_paths',
        verbose_name='学生'
    )

    # 路径信息
    name = models.CharField('路径名称', max_length=200)
    description = models.TextField('路径描述')
    status = models.CharField('状态', max_length=20, choices=Status.choices, default=Status.ACTIVE)

    # 目标和难度
    learning_goal = models.CharField('学习目标', max_length=300)
    difficulty_level = models.CharField('难度级别', max_length=20, default='medium')
    estimated_duration = models.IntegerField('预计学习时长(小时)', default=40)

    # 路径内容
    courses = models.JSONField('课程列表', default=list)
    modules = models.JSONField('模块列表', default=list)
    prerequisites = models.JSONField('前置要求', default=list)

    # 进度跟踪
    total_items = models.IntegerField('总项目数', default=0)
    completed_items = models.IntegerField('已完成项目数', default=0)
    current_item = models.JSONField('当前项目', default=dict, blank=True)

    # 时间规划
    start_date = models.DateField('开始日期', null=True, blank=True)
    target_date = models.DateField('目标完成日期', null=True, blank=True)
    actual_completion_date = models.DateField('实际完成日期', null=True, blank=True)

    # 推荐算法
    recommendation_algorithm = models.CharField('推荐算法', max_length=50, default='collaborative')
    adaptation_score = models.DecimalField('适应性评分', max_digits=3, decimal_places=2, default=0)

    # 创建者
    created_by = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='created_learning_paths',
        verbose_name='创建者'
    )

    class Meta:
        db_table = 'learning_paths'
        verbose_name = '学习路径'
        verbose_name_plural = '学习路径'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['user', 'status']),
            models.Index(fields=['difficulty_level']),
            models.Index(fields=['learning_goal']),
            models.Index(fields=['created_by']),
        ]

    def __str__(self):
        return f"{self.user.real_name} - {self.name}"

    def get_progress_percentage(self):
        """获取进度百分比"""
        if self.total_items == 0:
            return 0
        return (self.completed_items / self.total_items) * 100

    def update_progress(self, completed_count):
        """更新进度"""
        self.completed_items = completed_count
        if self.completed_items >= self.total_items:
            self.status = self.Status.COMPLETED
            self.actual_completion_date = timezone.now().date()
        self.save(update_fields=['completed_items', 'status', 'actual_completion_date'])


class LearningAnalytics(TimeStampedModel):
    """
    学习分析数据
    聚合的学习统计和分析结果
    """
    class AnalysisType(models.TextChoices):
        DAILY = 'daily', '日分析'
        WEEKLY = 'weekly', '周分析'
        MONTHLY = 'monthly', '月分析'
        COURSE = 'course', '课程分析'
        EXAM = 'exam', '考试分析'
        PERSONAL = 'personal', '个人分析'

    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='learning_analytics',
        verbose_name='用户',
        null=True,
        blank=True
    )

    # 分析信息
    analysis_type = models.CharField('分析类型', max_length=20, choices=AnalysisType.choices)
    period_start = models.DateField('分析开始日期')
    period_end = models.DateField('分析结束日期')

    # 学习时间统计
    total_study_time = models.IntegerField('总学习时间(分钟)', default=0)
    average_daily_time = models.IntegerField('日均学习时间(分钟)', default=0)
    productive_time = models.IntegerField('有效学习时间(分钟)', default=0)

    # 活动统计
    login_count = models.IntegerField('登录次数', default=0)
    session_count = models.IntegerField('学习会话数', default=0)
    activity_count = models.IntegerField('活动总数', default=0)

    # 学习效果
    engagement_score = models.DecimalField('参与度评分', max_digits=3, decimal_places=2, default=0)
    effectiveness_score = models.DecimalField('效果评分', max_digits=3, decimal_places=2, default=0)
    consistency_score = models.DecimalField('一致性评分', max_digits=3, decimal_places=2, default=0)

    # 知识掌握
    mastered_topics = models.JSONField('掌握的知识点', default=list)
    weak_areas = models.JSONField('薄弱环节', default=list)
    improvement_areas = models.JSONField('需改进领域', default=list)

    # 预测和建议
    performance_prediction = models.DecimalField('表现预测', max_digits=3, decimal_places=2, null=True, blank=True)
    recommendations = models.JSONField('学习建议', default=list)
    next_steps = models.JSONField('后续步骤', default=list)

    # 关联对象
    content_type = models.ForeignKey(
        'contenttypes.ContentType',
        on_delete=models.CASCADE,
        null=True,
        blank=True
    )
    object_id = models.UUIDField(null=True, blank=True)
    related_object = models.GenericForeignKey('content_type', 'object_id')

    # 原始数据
    raw_data = models.JSONField('原始数据', default=dict, blank=True)

    class Meta:
        db_table = 'learning_analytics'
        verbose_name = '学习分析'
        verbose_name_plural = '学习分析'
        ordering = ['-period_end']
        unique_together = [['user', 'analysis_type', 'period_start', 'period_end']]
        indexes = [
            models.Index(fields=['user', 'analysis_type']),
            models.Index(fields=['period_start', 'period_end']),
            models.Index(fields=['created_at']),
        ]

    def __str__(self):
        if self.user:
            return f"{self.user.real_name} - {self.get_analysis_type_display()}"
        return f"系统级 - {self.get_analysis_type_display()}"


class PerformanceMetrics(TimeStampedModel):
    """
    性能指标
    系统和用户的各项性能指标
    """
    class MetricType(models.TextChoices):
        RESPONSE_TIME = 'response_time', '响应时间'
        THROUGHPUT = 'throughput', '吞吐量'
        ERROR_RATE = 'error_rate', '错误率'
        SATISFACTION = 'satisfaction', '满意度'
        COMPLETION_RATE = 'completion_rate', '完成率'
        RETENTION = 'retention', '保持率'

    metric_type = models.CharField('指标类型', max_length=30, choices=MetricType.choices)
    metric_name = models.CharField('指标名称', max_length=100)
    metric_value = models.DecimalField('指标值', max_digits=10, decimal_places=4)

    # 关联对象
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='performance_metrics',
        verbose_name='用户',
        null=True,
        blank=True
    )

    # 时间和范围
    recorded_at = models.DateTimeField('记录时间', auto_now_add=True)
    time_period = models.CharField('时间周期', max_length=20, default='hourly')

    # 上下文信息
    context = models.JSONField('上下文信息', default=dict, blank=True)
    tags = models.JSONField('标签', default=list, blank=True)

    class Meta:
        db_table = 'performance_metrics'
        verbose_name = '性能指标'
        verbose_name_plural = '性能指标'
        ordering = ['-recorded_at']
        indexes = [
            models.Index(fields=['metric_type', 'recorded_at']),
            models.Index(fields=['user', 'metric_type']),
            models.Index(fields=['recorded_at']),
        ]

    def __str__(self):
        return f"{self.metric_name}: {self.metric_value}"


class LearningRecommendation(TimeStampedModel):
    """
    学习推荐
    基于分析结果生成个性化推荐
    """
    class RecommendationType(models.TextChoices):
        COURSE = 'course', '课程推荐'
        CONTENT = 'content', '内容推荐'
        STUDY_METHOD = 'study_method', '学习方法'
        TIME_MANAGEMENT = 'time_management', '时间管理'
        SKILL_DEVELOPMENT = 'skill_development', '技能发展'
        EXAM_PREPARATION = 'exam_preparation', '考试准备'

    class Status(models.TextChoices):
        PENDING = 'pending', '待处理'
        ACCEPTED = 'accepted', '已接受'
        REJECTED = 'rejected', '已拒绝'
        IMPLEMENTED = 'implemented', '已实施'

    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='learning_recommendations',
        verbose_name='学生'
    )

    # 推荐信息
    recommendation_type = models.CharField('推荐类型', max_length=30, choices=RecommendationType.choices)
    title = models.CharField('推荐标题', max_length=200)
    description = models.TextField('推荐描述')
    priority = models.IntegerField('优先级', default=1, help_text='1-5，数字越大优先级越高')

    # 推荐内容
    recommended_items = models.JSONField('推荐项目', default=list)
    action_steps = models.JSONField('行动步骤', default=list)
    expected_outcome = models.TextField('预期效果', blank=True)
    time_commitment = models.IntegerField('时间投入(小时)', null=True, blank=True)

    # 推荐依据
    based_on_analysis = models.ForeignKey(
        LearningAnalytics,
        on_delete=models.CASCADE,
        related_name='recommendations',
        verbose_name='基于分析',
        null=True,
        blank=True
    )
    confidence_score = models.DecimalField('置信度评分', max_digits=3, decimal_places=2, default=0)

    # 处理状态
    status = models.CharField('状态', max_length=20, choices=Status.choices, default=Status.PENDING)
    user_feedback = models.TextField('用户反馈', blank=True)
    implementation_notes = models.TextField('实施备注', blank=True)

    # 时间信息
    valid_until = models.DateTimeField('有效期至', null=True, blank=True)
    implemented_at = models.DateTimeField('实施时间', null=True, blank=True)

    class Meta:
        db_table = 'learning_recommendations'
        verbose_name = '学习推荐'
        verbose_name_plural = '学习推荐'
        ordering = ['-priority', '-created_at']
        indexes = [
            models.Index(fields=['user', 'status']),
            models.Index(fields=['recommendation_type']),
            models.Index(fields=['priority']),
            models.Index(fields=['valid_until']),
        ]

    def __str__(self):
        return f"{self.user.real_name} - {self.title}"

    def is_valid(self):
        """检查推荐是否仍然有效"""
        if not self.valid_until:
            return True
        return timezone.now() <= self.valid_until

    def mark_as_implemented(self, feedback='', notes=''):
        """标记为已实施"""
        self.status = self.Status.IMPLEMENTED
        self.user_feedback = feedback
        self.implementation_notes = notes
        self.implemented_at = timezone.now()
        self.save(update_fields=['status', 'user_feedback', 'implementation_notes', 'implemented_at'])